package com.zenithmind.disk.pojo.domain;

import com.zenithmind.common.base.BaseEntity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import io.swagger.v3.oas.annotations.media.Schema;

/**
 * 用户云盘实体类
 * 遵循单一职责原则：专注于用户存储空间数据的表示和基本操作
 * 遵循开闭原则：通过方法封装，便于扩展
 */
@EqualsAndHashCode(callSuper = true)
@Data
@AllArgsConstructor
@NoArgsConstructor
@Schema(name = "用户，存储用户信息实体", description = "用户，存储用户信息实体")
public class UserCloudDisk extends BaseEntity {

    @Schema(description = "总空间，单位为字节，默认1GB")
    private Long storageLimit;

    @Schema(description = "已使用空间，单位为字节")
    private Long storageUsed;

    // ==================== 常量定义 ====================

    /** 默认存储限制：1GB */
    public static final long DEFAULT_STORAGE_LIMIT = 1024L * 1024L * 1024L;

    /** 免费用户存储限制：1GB */
    public static final long FREE_USER_STORAGE_LIMIT = 1024L * 1024L * 1024L;

    /** VIP用户存储限制：100GB */
    public static final long VIP_USER_STORAGE_LIMIT = 100L * 1024L * 1024L * 1024L;

    // ==================== 业务方法 ====================

    /**
     * 获取剩余存储空间
     * @return 剩余存储空间（字节）
     */
    public long getRemainingStorage() {
        if (storageLimit == null || storageUsed == null) {
            return 0;
        }
        return Math.max(0, storageLimit - storageUsed);
    }

    /**
     * 获取存储使用率
     * @return 存储使用率（0.0-1.0）
     */
    public double getStorageUsageRate() {
        if (storageLimit == null || storageLimit == 0 || storageUsed == null) {
            return 0.0;
        }
        return Math.min(1.0, (double) storageUsed / storageLimit);
    }

    /**
     * 获取存储使用百分比
     * @return 存储使用百分比（0-100）
     */
    public int getStorageUsagePercentage() {
        return (int) Math.round(getStorageUsageRate() * 100);
    }

    /**
     * 检查存储空间是否充足
     * @param requiredSize 需要的空间大小（字节）
     * @return true如果空间充足
     */
    public boolean hasEnoughStorage(long requiredSize) {
        return getRemainingStorage() >= requiredSize;
    }

    /**
     * 检查存储空间是否即将用完（使用率超过90%）
     * @return true如果存储空间即将用完
     */
    public boolean isStorageAlmostFull() {
        return getStorageUsageRate() >= 0.9;
    }

    /**
     * 检查存储空间是否已满（使用率超过95%）
     * @return true如果存储空间已满
     */
    public boolean isStorageFull() {
        return getStorageUsageRate() >= 0.95;
    }

    /**
     * 增加已使用存储空间
     * @param size 增加的大小（字节）
     */
    public void addStorageUsed(long size) {
        if (storageUsed == null) {
            storageUsed = 0L;
        }
        storageUsed += size;
    }

    /**
     * 减少已使用存储空间
     * @param size 减少的大小（字节）
     */
    public void reduceStorageUsed(long size) {
        if (storageUsed == null) {
            storageUsed = 0L;
        }
        storageUsed = Math.max(0, storageUsed - size);
    }

    /**
     * 格式化存储限制为可读字符串
     * @return 格式化后的存储限制字符串
     */
    public String getFormattedStorageLimit() {
        return formatBytes(storageLimit);
    }

    /**
     * 格式化已使用存储为可读字符串
     * @return 格式化后的已使用存储字符串
     */
    public String getFormattedStorageUsed() {
        return formatBytes(storageUsed);
    }

    /**
     * 格式化剩余存储为可读字符串
     * @return 格式化后的剩余存储字符串
     */
    public String getFormattedRemainingStorage() {
        return formatBytes(getRemainingStorage());
    }

    /**
     * 设置为免费用户存储限制
     */
    public void setFreeUserStorageLimit() {
        this.storageLimit = FREE_USER_STORAGE_LIMIT;
    }

    /**
     * 设置为VIP用户存储限制
     */
    public void setVipUserStorageLimit() {
        this.storageLimit = VIP_USER_STORAGE_LIMIT;
    }

    /**
     * 升级存储空间
     * @param newLimit 新的存储限制
     */
    public void upgradeStorage(long newLimit) {
        if (newLimit > (storageLimit != null ? storageLimit : 0)) {
            this.storageLimit = newLimit;
        }
    }

    /**
     * 验证用户云盘数据的完整性
     * @return true如果数据有效
     */
    public boolean isValid() {
        return storageLimit != null && storageLimit > 0 &&
               storageUsed != null && storageUsed >= 0 &&
               storageUsed <= storageLimit;
    }

    /**
     * 格式化字节数为可读字符串的私有方法
     * @param bytes 字节数
     * @return 格式化后的字符串
     */
    private String formatBytes(Long bytes) {
        if (bytes == null || bytes <= 0) {
            return "0 B";
        }

        String[] units = {"B", "KB", "MB", "GB", "TB"};
        double size = bytes.doubleValue();
        int unitIndex = 0;

        while (size >= 1024 && unitIndex < units.length - 1) {
            size /= 1024;
            unitIndex++;
        }

        return String.format("%.2f %s", size, units[unitIndex]);
    }
}
